﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LotteryVote.Data;
using LotteryVote.Entity;
using LotteryVote.Logic.Exceptions;

namespace LotteryVote.Logic
{
    public class CommisionGroupFacade
    {
        private ConcreteCommissionDataAccess _daConcreteComm;
        internal ConcreteCommissionDataAccess DaConcreteComm
        {
            get
            {
                if (_daConcreteComm == null)
                    _daConcreteComm = new ConcreteCommissionDataAccess();
                return _daConcreteComm;
            }
            set
            {
                _daConcreteComm = value;
            }
        }

        private CommissionGroupDataAccess _daCommisionGroup;
        internal CommissionGroupDataAccess DaCommisionGroup
        {
            get
            {
                if (_daCommisionGroup == null)
                    _daCommisionGroup = new CommissionGroupDataAccess();
                return _daCommisionGroup;
            }
            set
            {
                _daCommisionGroup = value;
            }
        }

        private GameTypeDataAccess _daGameType;
        internal GameTypeDataAccess DaGameType
        {
            get
            {
                if (_daGameType == null)
                    _daGameType = new GameTypeDataAccess();
                return _daGameType;
            }
            set
            {
                _daGameType = value;
            }
        }

        private CompanyTypeDataAccess _daComType;
        internal CompanyTypeDataAccess DaCompanyType
        {
            get
            {
                if (_daComType == null)
                    _daComType = new CompanyTypeDataAccess();
                return _daComType;
            }
            set
            {
                _daComType = value;
            }
        }

        private LotterySpecieDataAccess _daSpecie;
        internal LotterySpecieDataAccess DaSpecie
        {
            get
            {
                if (_daSpecie == null)
                    _daSpecie = new LotterySpecieDataAccess();
                return _daSpecie;
            }
            set
            {
                _daSpecie = value;
            }
        }

        public void AddCommissionGroup(int specieId, string groupName, IList<CommissionItem> commissionList)
        {
            if (string.IsNullOrEmpty(groupName))
                throw new ArgumentNullException("groupName");
            if (commissionList == null)
                throw new ArgumentNullException("commissionList");

            if (IsExistCommissionGroup(specieId, groupName)) return;

            List<CompanyTypeModel> companyTypeList = new List<CompanyTypeModel>();
            List<GameType> gameTypeList = new List<GameType>();
            DaCommisionGroup.ExecuteWithTransaction(() =>
            {
                CommissionGroup group = new CommissionGroup
                {
                    GroupName = groupName,
                    SpecieId = specieId
                };
                DaCommisionGroup.InsertCommissionGroup(group);

                DaConcreteComm.Tandem(DaCommisionGroup);
                DaCompanyType.Tandem(DaCommisionGroup);
                DaGameType.Tandem(DaCommisionGroup);
                foreach (var item in commissionList)
                {
                    var comType = companyTypeList.Find(it => it.Id == item.CompanyTypeId);
                    if (comType == null)
                    {
                        comType = DaCompanyType.GetCompanyType(item.CompanyTypeId);
                        companyTypeList.Add(comType);
                    }
                    var gameType = gameTypeList.Find(it => it.GameId == item.GameTypeId);
                    if (gameType == null)
                    {
                        gameType = DaGameType.GetGameType(item.GameTypeId);
                        gameTypeList.Add(gameType);
                    }

                    ConcreteCommission concreteComm = new ConcreteCommission
                    {
                        Group = group,
                        CompanyType = comType,
                        GameType = gameType,
                        Commission = item.Commission,
                        Odds = item.Odds
                    };
                    DaConcreteComm.InsertConcreteCommission(concreteComm);
                }
            });
        }
        public void UpdateCommissionGroup(int groupId, IList<CommissionItem> commissionList)
        {
            List<CompanyTypeModel> companyTypeList = new List<CompanyTypeModel>();
            List<GameType> gameTypeList = new List<GameType>();
            DaConcreteComm.ExecuteWithTransaction(() =>
            {
                DaConcreteComm.ClearConcreteCommission(groupId);
                DaCommisionGroup.Tandem(DaConcreteComm);
                var group = DaCommisionGroup.GetCommissionGroup(groupId);
                if (group == null)
                    throw new InvalidDataException("group,groupId:" + groupId);
                DaCompanyType.Tandem(DaConcreteComm);
                DaGameType.Tandem(DaConcreteComm);

                foreach (var item in commissionList)
                {
                    var comType = companyTypeList.Find(it => it.Id == item.CompanyTypeId);
                    if (comType == null)
                    {
                        comType = DaCompanyType.GetCompanyType(item.CompanyTypeId);
                        companyTypeList.Add(comType);
                    }
                    var gameType = gameTypeList.Find(it => it.GameId == item.GameTypeId);
                    if (gameType == null)
                    {
                        gameType = DaGameType.GetGameType(item.GameTypeId);
                        gameTypeList.Add(gameType);
                    }

                    ConcreteCommission concreteComm = new ConcreteCommission
                    {
                        Group = group,
                        CompanyType = comType,
                        GameType = gameType,
                        Commission = item.Commission,
                        Odds = item.Odds
                    };
                    DaConcreteComm.InsertConcreteCommission(concreteComm);
                }
            });
        }
        public void RemoveCommissionGroup(int groupId)
        {
            DaCommisionGroup.DeleteCommissionGroup(groupId);
        }

        /// <summary>
        ///是否存在同名分组.
        /// </summary>
        /// <param name="specieId">The specie id.</param>
        /// <param name="groupName">Name of the group.</param>
        /// <returns>
        ///   <c>true</c> if [is exist commission group] [the specified specie id]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsExistCommissionGroup(int specieId, string groupName)
        {
            if (string.IsNullOrEmpty(groupName))
                throw new ArgumentNullException("groupName");
            return DaCommisionGroup.GetCommissionGroup(specieId, groupName) != null;
        }
        public CommissionGroupModel GetCommissionGroupModel(int groupId)
        {
            var model = DaCommisionGroup.GetCommissionGroupModel(groupId);
            //var result = model.ConcreteCommissionList.GroupBy(it => it.CompanyType.Id);
            return model;
        }
        public CommissionGroupModel GetCommissionGropModelByMember(User user, LotterySpeciesEnum specie)
        {
            if (user.Role != SystemRole.Guest)
                throw new InvalidRoleException(SystemRole.Guest, user.Role);
            return DaCommisionGroup.GetCommissionGroupModelByMember(user, specie);
        }
        public CommissionGroup GetCommissionGroup(int groupId)
        {
            return DaCommisionGroup.GetCommissionGroup(groupId);
        }
        public IList<CommissionGroupModel> GetCommissionGroupBySpecie(int specieId)
        {
            var specie = DaSpecie.GetSpecie(specieId);
            if (specie == null)
                throw new InvalidDataException("speice,SpecieId:" + specieId);
            return DaCommisionGroup.GetCommissionGroupBySpecie(specie);
        }
        public IList<CommissionGroup> GetAllCommissionGroup()
        {
            return DaCommisionGroup.GetAll();
        }
        public IList<CommissionGroup> GetCommissionGroupBySpecie(LotterySpeciesEnum specie)
        {
            return DaCommisionGroup.GetCommissionGroupBySpecie(specie);
        }
    }
}
